package s

import "encoding/hex"

// 8 rank m sequence f(x) = x^8 + x^4 + x^3 + x^2 + 1
func ByteMSeq(c byte) (next byte) {
	if c == 0 {
		c = 0b10000000
	}
	c2 := c & 0b10001110
	b := uint8(0)
	for _, i := range []uint8{7, 3, 2, 1} {
		b = (b + (c2 >> i)) & 0b1
		// fmt.Println(i, " ", (c2>>i)&0b1, " ", b)
	}
	return (b << 7) + (c >> 1)
}

// MBytes return small-m sequence , for every byte in bytes , will use ByteMSeq to generate a new byte
func (b Bytes) MBytes() Bytes {
	nb := MakeBytes(b.Len())
	for i, bi := range b {
		nb[i] = ByteMSeq(bi)
	}
	return nb
}

func (b Bytes) HXor(k Bytes) (db Bytes) {
	kl := k.Len()
	db = MakeBytes(b.Len())
	for no, bi := range b {
		ki := k[no%kl]
		db[no] = bi ^ ki
		k = k.MBytes()
	}
	return
}

func (b Bytes) Hex() Str {
	return Str(hex.EncodeToString(b))
}

func (self Str) HXorHex(k string) (hexS Str) {
	if b2, err := hex.DecodeString(self.String()); err != nil {
		return self.Encode().HXor(Bytes(k)).Hex()
	} else {
		return Bytes(b2).HXor(Bytes(k)).Decode()
	}
}
